import React, { createContext, useState } from "react";
import { ConfigProvider as AntdConfigProvider } from "antd";
import zhCN from "antd/locale/zh_CN";
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn'
import { hasHttpOrHttps } from "../utils/fun.ts";
import type { Page, CommonNodesMap, ApiUrl, AppConfig, Theme, Pages, CommonNodes, FieldIdentifiers, UserData, MenuItem  } from "../global.ts";
import type { AuthMode } from "../component/AuthForm/index.tsx";
import type { AuthFormConfig } from "../pages/AdminPages/AuthPage.tsx";

dayjs.locale('zh-cn');

export interface IConfig {
  token: string;
  setToken: React.Dispatch<React.SetStateAction<string>>;
  userInfo: UserData;
  pages: Page[];
  commonNodes: CommonNodesMap;
  useLoad?: () => void;
  setUserInfo: React.Dispatch<React.SetStateAction<UserData>>;
  tokenKey: string;
  apiUrl: ApiUrl;
  theme: Theme;
  setTheme: React.Dispatch<React.SetStateAction<Theme>>;
  userMenu: MenuItem[];
  setUserMenu: React.Dispatch<React.SetStateAction<MenuItem[]>>;
  sysConfig: { [key: string]: any };
  setSysConfig: React.Dispatch<React.SetStateAction<{ [key: string]: any }>>;
  appConfig: AppConfig;
  /**
   * 拼接 host 和 src
   * @param src - 资源路径
   * @returns 拼接后的完整路径
   */
  getSrc: (src: string) => string;
  notificationNode?: React.ReactNode;
  menuFieldIdentifiers?: FieldIdentifiers;
  /** 是否显示管理员菜单 */
  showAdminMenu?: boolean;
  /** 是否使用 SPA 路由 */
  useSpaRouter?: boolean;
  defaultUserMenu?: MenuItem[];
  /** 认证模式 */
  authMode?: AuthMode;
  /** 认证表单配置 */
  authConfig?: AuthFormConfig;
  /** 加载器路径 */
  loaderPath?: string;
  /** 侧边栏是否默认收起 */
  defaultCollapsed?: boolean;
}

// 定义默认的配置参数
const defaultConfig: IConfig = {
  token: "",
  setToken: () => {},
  userInfo: {} as UserData,
  pages: [],
  commonNodes: new Map(),
  setUserInfo: () => {},
  tokenKey: "",
  apiUrl: {} as ApiUrl,
  theme: "light",
  setTheme: () => {},
  userMenu: [] as MenuItem[],
  setUserMenu: () => {},
  sysConfig: {},
  setSysConfig: () => {},
  appConfig: {} as AppConfig,
  getSrc: (src: string) => src,
  notificationNode: undefined,
  menuFieldIdentifiers: undefined,
  showAdminMenu: true,
  useSpaRouter: false,
  defaultUserMenu: [],
  authMode: 'login-only',
  authConfig: undefined,
  loaderPath: 'admin',
  defaultCollapsed: false,
};

const ConfigContext = createContext<IConfig>(defaultConfig);

export const useConfig = () => {
  const context = React.useContext(ConfigContext);
  return context;
};

export interface ConfigContextProps {
  apiUrl: ApiUrl;
  tokenKey: string;
  appConfig: AppConfig;
  pages: Pages;
  commonNodes: CommonNodes;
  useLoad?: () => void;
  notificationNode?: React.ReactNode;
  children: React.ReactNode;
  defaultUserMenu?: MenuItem[];
  menuFieldIdentifiers?: FieldIdentifiers;
  showAdminMenu?: boolean;
  useSpaRouter?: boolean;
  /** 认证模式 */
  authMode?: AuthMode;
  /** 认证表单配置 */
  authConfig?: AuthFormConfig;
  /** 加载器路径 */
  loaderPath?: string;
  defaultCollapsed?: boolean;
}

export const ConfigProvider: React.FC<ConfigContextProps> = ({
  apiUrl,
  appConfig,
  tokenKey,
  pages,
  commonNodes,
  useLoad,
  notificationNode,
  children,
  defaultUserMenu = [],
  menuFieldIdentifiers,
  showAdminMenu = true,
  useSpaRouter = false,
  authMode = 'login-only',
  authConfig,
  loaderPath = 'admin',
  defaultCollapsed,
}: ConfigContextProps) => {
  const [token, setToken] = useState("");
  const [userInfo, setUserInfo] = useState<UserData>();
  const [userMenu, setUserMenu] = useState<MenuItem[]>([]);
  const [sysConfig, setSysConfig] = useState<{ [key: string]: any }>({});
  const [theme, setTheme] = useState<Theme>("light");

  const commonNodesMap = new Map(
    commonNodes?.map((node) => [node.name, node.node])
  );

  const getSrc = (src: string) => {
    const ossHost = appConfig?.ossBaseUrl || "";
    if (!ossHost) return src;
    const concatHost = (host: string, src: string) => {
      // 如果 host 为空，则直接返回 src
      if (!host) return src;

      // 如果 src 已经包含 http 或 https，则直接返回 src
      if( hasHttpOrHttps(src)) return src;

      // 如果 host 以 / 结尾，则直接拼接 src
      if (host.endsWith('/')) {
        return `${host}${src}`;
      }

      // 否则，拼接 src
      return `${host}/${src}`;
    }
    return concatHost(ossHost, src);
  };

  const mixMenuList = (menuList:MenuItem[])=>{
    setUserMenu([...(defaultUserMenu || []),...(menuList || [])]);
  }

  return (
    <AntdConfigProvider locale={zhCN}>
      <ConfigContext.Provider
        value={{
          token,
          setToken,
          userInfo,
          setUserInfo,
          tokenKey,
          apiUrl,
          theme,
          setTheme,
          userMenu,
          setUserMenu:mixMenuList,
          sysConfig,
          setSysConfig,
          appConfig,
          getSrc,
          pages,
          commonNodes: commonNodesMap,
          useLoad,
          notificationNode,
          menuFieldIdentifiers,
          showAdminMenu,
          useSpaRouter,
          defaultUserMenu,
          authMode,
          authConfig,
          loaderPath,
          defaultCollapsed,
        }}
      >
        {children}
      </ConfigContext.Provider>
    </AntdConfigProvider>
  );
};
